package com.xuzhiguang.baidu.pan.sdk.operations;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.xuzhiguang.baidu.pan.sdk.common.http.HttpClient;
import com.xuzhiguang.baidu.pan.sdk.configuration.BaiduPanConfiguration;
import com.xuzhiguang.baidu.pan.sdk.exception.BaiduPanSdkException;
import com.xuzhiguang.baidu.pan.sdk.model.*;
import com.xuzhiguang.baidu.pan.sdk.token.ITokenStorage;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author xuzhiguang
 * @date 2020/6/27 0:07
 */
public class BaiduPanUploadOperations extends BaiduPanOperations {

    public BaiduPanUploadOperations(HttpClient httpClient, ITokenStorage tokenStorage, BaiduPanConfiguration baiduPanConfiguration) {
        super(httpClient, tokenStorage, baiduPanConfiguration);
    }

    /**
     * https://pan.baidu.com/union/document/upload#预上传
     * 预上传
     *
     * 支持MD5文件验证秒传
     * @param params
     * @return
     * @throws BaiduPanSdkException
     */
    public UploadPreCreateResult preCreate(UploadPreCreateParams params) throws BaiduPanSdkException {

        String url = this.baiduPanApiUrlPrefix + "/xpan/file";
        Map<String, String> parameters = new LinkedHashMap<>();
        parameters.put("method", "precreate");

        if (params.getPath() == null) {
            throw new IllegalArgumentException("参数 path 不能为空");
        }

        if (params.getSize() == null) {
            throw new IllegalArgumentException("参数 size 不能为空");
        }

        if (params.getIsdir() == null) {
            throw new IllegalArgumentException("参数 isdir 不能为空");
        }

        if (params.getAutoinit() == null) {
            throw new IllegalArgumentException("参数 autoinit 不能为空");
        }

        if (params.getBlockList() == null) {
            throw new IllegalArgumentException("参数 block_list 不能为空");
        }

        Map<String, String> paramsMap = beanToMap(params);


        // block_list是Array类型，需要手动处理
        try {
            paramsMap.put("block_list", objectMapper.writeValueAsString(params.getBlockList()));
        } catch (JsonProcessingException e) {
            throw new BaiduPanSdkException("json 序列化失败", e);
        }

        JavaType javaType = this.objectMapper.constructType(UploadPreCreateResult.class);
        return this.postFormData(url, parameters, null, paramsMap, true, javaType);
    }

    /**
     * https://pan.baidu.com/union/document/upload#分片上传
     * 分片上传
     * @param params
     * @return
     * @throws BaiduPanSdkException
     */
    public UploadPartUploadResult partUpload(UploadPartUploadParams params) throws BaiduPanSdkException {

        String url = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2";
        Map<String, String> parameters = new LinkedHashMap<>();

        byte[] file = params.getFile();
        String fileKey = "file";
        String fileName = "blob";
        params.setFile(null);

        Map<String, String> paramsMap = beanToMap(params);
        parameters.putAll(paramsMap);

        JavaType javaType = this.objectMapper.constructType(UploadPartUploadResult.class);
        return this.postMultipart(url, parameters, null, null, fileKey, fileName, file, true, javaType);
    }


    /**
     * https://pan.baidu.com/union/document/upload#创建文件
     * 创建文件
     * @param params
     * @return
     * @throws BaiduPanSdkException
     */
    public UploadCreateResult create(UploadCreateParams params) throws BaiduPanSdkException {
        String url = this.baiduPanApiUrlPrefix + "/xpan/file";
        Map<String, String> parameters = new LinkedHashMap<>();
        parameters.put("method", "create");

        if (params.getPath() == null) {
            throw new IllegalArgumentException("参数 path 不能为空");
        }

        if (params.getSize() == null) {
            throw new IllegalArgumentException("参数 size 不能为空");
        }

        if (params.getIsdir() == null) {
            throw new IllegalArgumentException("参数 isdir 不能为空");
        }

        Map<String, String> paramsMap = beanToMap(params);

        if (params.getBlockList() != null && params.getBlockList().size() > 0) {
            // block_list是Array类型，需要手动处理
            try {
                paramsMap.put("block_list", objectMapper.writeValueAsString(params.getBlockList()));
            } catch (JsonProcessingException e) {
                throw new BaiduPanSdkException("json 序列化失败", e);
            }
        }

        JavaType javaType = this.objectMapper.constructType(UploadCreateResult.class);
        return this.postFormData(url, parameters, null, paramsMap, true, javaType);
    }

}
